import { useEffect } from 'react';
import {
  Input, Button, Form,
  Radio, Space, Select, message,
  DatePicker, Checkbox, Upload, Divider
} from 'antd';

import {
  InboxOutlined
} from '@ant-design/icons';

import './previewModal.less';
import fieldShowRuleFn from '@/pages/Drag/sub-components/previewModal/fieldShowRule';

import StaffTree from '@/components/ComponentConfig/StaffTree';
import OrgTree from '@/components/ComponentConfig/OrgTree';
import formulas from './formulas';
import SubForm from '@/components/SubForm';
import DragApi from '../../service';
import parseFormulas from './parseFormulas';
import moment from 'moment';

const { RangePicker } = DatePicker;
const { Dragger } = Upload;
const { TextArea } = Input;

type PropsType = {
  formData: any;
  setFormData: Function;
  onPreviewFormSubmit: Function;
  rules: any;
  formEvents: any;
}

function PreviewForm(props: PropsType) {
  const { formData, setFormData, formEvents } = props;

  //监听数据 计算公式 实时更新
  function watchFormRely(data: any[]) {
    data.forEach((item: any) => {
      if (item.rely) {

        const { formula, type } = item.rely.formula;
			  const args = parseFormulas(formula,formData);
        const formulasKeys = Object.keys(formulas);
        // console.log(formulasKeys.length);
        const fkey = formula.split("(")[0];
        const key = formulasKeys.find(v => v===fkey);

        if (key) {
          let res = formulas[key](...args);
          item.value = res;
        }
      }
    })

    // console.log('data',data)
    props.setFormData(data);
  }
  function getFieldEvent(id: any) {
    if (!formEvents) return false;
    const getItem = Object.values(formEvents)?.find((item: any) => id === item.trigger);
    return getItem;
  }

  useEffect(() => {
    executeEventJson({ id: 'initialValue' });
  }, [formEvents])

  // 前端事件执行
  async function executeEventJson(dataItem: any) {
    const eventJson: any = getFieldEvent(dataItem.id);
    if (!eventJson) return;
    message.loading('加载中...');
    let resData = await DragApi.customRequest(eventJson.request);
    resData = JSON.stringify(resData);
    if (eventJson.action.length) {
      eventJson.action.map((item: any) => {
        const pannet = /(\$\{).*?(\})/g;
        const data = [...formData];
        const getField = formData.findIndex((n: any) => n.id === item.name);
        const newStr = item.value.replace(pannet, (word: string) => {
          const newWord = word.replace(/(\$\{)|(\})/g, '');
          if (newWord.includes('[') && newWord.includes(']')) {
            const newFn = new Function(`return ${resData}['data']${newWord}`);
            return newFn();
          } else {
            const otherIndex = formData.findIndex((n: any) => n.id === newWord)
            return formData[otherIndex].value;
          }
        })
        data[getField].value = newStr;
        watchFormRely(data);
      })
    }
    message.destroy();
  }


  function radioRender(item: any, index: number) {
    const { props: itemProps } = item;
    function onRadioGroupChange(e: any) {
      // console.log(e.target.value)
      const data = [...formData];
      data[index].value = e.target.value;
      watchFormRely(data);
      executeEventJson(item);
    }
    return (
      <Radio.Group onChange={onRadioGroupChange} value={item.value}>
        <Space direction={itemProps.vertical ? "vertical" : 'horizontal'}>
          {itemProps.options.map((r: any) => (
            <Radio key={r.value} value={r.value}>
              {r.label}
            </Radio>
          ))}
        </Space>
      </Radio.Group>
    )
  }
  function selectRender(item: any, index: number) {
    // console.log(item)
    const { props: itemProps } = item;
    const onSelectChange = (val: string) => {
      // return console.log(val)
      const data = [...formData];
      data[index].value = val;
      watchFormRely(data);
      executeEventJson(item);
    }
    const compProps = {
      style: { width: "100%" },
      options: itemProps.options,
      onChange: onSelectChange,
      placeholder: itemProps.tip
    }
    return itemProps.multiple ? (
      <Select {...compProps} mode="multiple" />
    ) : (
      <Select {...compProps} />
    )
  }

  function InputRender(item: any, index: number) {

    const { props: itemProps } = item;

    const { edit } = item.fieldPermissions;
    const onInputChange = (e: any) => {
      const val = e.target.value;
      // console.log(val);
      const data = [...formData];
      data[index].value = val;
      // setFormData(data);
			watchFormRely(data)
      executeEventJson(item);
    }
    const onBlur = () => {
      if (!item.value) return;
      const re = {
        'phone': {
          re: /^1\d{10}$/,
          errMsg: '请输入正确的手机号码'
        },
        'mobeil': {
          re: /^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/,
          errMsg: '请输入正确的电话号码格式'
        },
        'IDcard': {
          re: /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}(\d|X|x)$/,
          errMsg: '请输入正确的身份证号'
        },
        'email': {
          re: /^\w+@[a-z0-9]+\.[a-z]+$/i,
          errMsg: '请输入正确的邮箱地址'
        },
      }

      const check = !itemProps.format ? true : re[itemProps.format].re.test(item.value);

      // console.log(item.value,check,re[item.format]);
      if (!check) {
        message.warn(re[itemProps.format].errMsg)
        const data = [...formData];
        data[index].value = '';
        setFormData(data);
      }

    }

    const props = {
      type: itemProps.format,
      allowClear: true,
      value: item.value,
      placeholder: itemProps.tip,
      defaultValue: item.value,
      onChange: onInputChange,
      onBlur: onBlur,
      disabled: !edit,
    }
    return !itemProps.textarea ? (
      <Input {...props} />
    ) : (
      <TextArea {...props} />
    )
  }
  function datePickerRender(item: any, index: number) {
    // console.log('datePickerRender',item);

    const { props: itemProps } = item;

    const onChange = (date: any, dateString: string) => {
      // console.log(date, dateString);
      const data = [...formData];
      const timeStemp =  moment(date).valueOf(); 
      data[index].value = timeStemp;
      // setFormData(data);
      watchFormRely(data);
      executeEventJson(item);
    }
    const time:any = item.value ? moment(item.value) 
    : itemProps.swDefaultValue ? itemProps.defaultValue : '';
    
    return (
      <DatePicker
        onChange={onChange}
        placeholder={itemProps.tip}
        allowClear={itemProps.allowClear}
        picker={itemProps.picker}
        showTime={itemProps.showTime}
        showToday={itemProps.showToday}
        value={time}
      />
    )
  }

  function dateRangeRender(item: any, index: number) {
    const { props: itemProps } = item;

    const onChange = (values: any, formatString: any) => {
      // console.log(values, formatString);
      const data = [...formData];
      data[index].value = values;
      watchFormRely(data);
      executeEventJson(item);
    }
    return (
      <RangePicker
        onChange={onChange}
        placeholder={itemProps.tip}
        allowClear={itemProps.allowClear}
        picker={itemProps.picker}
        showTime={itemProps.showTime}
        defaultValue={itemProps.defaultValue}
        value={item.value}
      />
    )
  }

  function checkboxRender(item: any, index: number) {

    const { props: itemProps } = item;

    // console.log(item)
    const onChange = (val: any) => {
      // console.log(val)
      const data = [...formData];
      data[index].value = val;
      watchFormRely(data);
      executeEventJson(item);
    }
    return (
      <Checkbox.Group
        onChange={onChange}
        value={item.value}
      >
        {itemProps.options.map((v: any) => (
          <div key={v.value} style={{ display: itemProps.direction === 'vertical' ? 'block' : 'inline-block' }}>
            <Checkbox value={v.value} > {v.label} </Checkbox>
          </div>
        ))}
      </Checkbox.Group>
    )
  }
  function uploadRender(item: any, index: number) {

    const { props: itemProps } = item;

    const compProps = {
      name: item.field,
      multiple: itemProps.multiple,
      action: itemProps.action,
      maxCount: itemProps.maxCount,
      listType: itemProps.listType,

      onChange(info: any) {
        const { status } = info.file;
        if (status !== 'uploading') {
          console.log(info.file, info.fileList);
        }
        if (status === 'done') {
          message.success(`${info.file.name} 上传成功`);

          const data = [...formData];
          data[index].value = info.file.response.url;
          setFormData(data);
          executeEventJson(item);

        } else if (status === 'error') {
          message.error(`${info.file.name} 上传失败`);
        }
      },
      onDrop(e: any) {
        console.log('Dropped files', e.dataTransfer.files);
      },
    };

    return (
      <Dragger {...compProps} className="dragUpload">
        <p className="icon">
          <InboxOutlined />
        </p>
        <p className="text">选择或拖拽上传文件,单个200MB以内</p>

      </Dragger>
    )
  }

  function staffTreeRender(item: any, index: number) {

    const onSelectChange = (data: any[]) => {
      console.log(data)
      const fdata = [...formData];
      fdata[index].value = data;
      watchFormRely(fdata);
      executeEventJson(item);
    }
    return (
      <StaffTree
        multiple={item.multiple}
        onSelectChange={onSelectChange}
      />
    )
  }

  function orgTreeRender(item: any, index: number) {
    const onSelectChange = (data: any[]) => {
      // console.log(data)
      const fdata = [...formData];
      fdata[index].value = data;
      watchFormRely(fdata);
      executeEventJson(item);
    }
    return (
      <OrgTree
        multiple={item.multiple}
        onSelectChange={onSelectChange}
      />
    )
  }

  function splitLineRender(item: any, index: number) {
    const { styles } = item;
    return (
      <div className="splitLine">
        {item.showTit && <h4 className="tit" style={{ color: styles.titColor }}>{item.tit}</h4>}
        <Divider
          className="divider"
          dashed={styles.dashed}
          style={{ borderColor: styles.lineColor }}
        />
        <p className="splitDesc">{item.splitDesc}</p>
      </div>
    )
  }

  const subFormRender = (item: any, index: number) => {

    const onSubFormChange = (data: any[]) => {
      // console.log(data);
      // return
      const fdata = [...formData];
      fdata[index].children = data;

      const resArr: any = [];
      data.forEach(item => {
        const obj = {}
        item.forEach((item2: any) => {
          if (item2.field) {
            obj[item2.field] = item2.value;
          }
        })
        resArr.push(obj)
      })
      fdata[index].value = resArr;
      // console.log({resArr})
      setFormData(fdata);
    }
    return (
      <SubForm
        subFormObj={item}
        onSubFormChange={onSubFormChange}
      />
    )
  }


  //显隐规则校验
  function fieldShowRule(id: string): boolean {
    return fieldShowRuleFn(id, props.rules, formData);
  }

  function submit() {
    // console.log('form layout Data:',formData)
    const reqParams: any = {};
    let check = true;
    for (let i = 0; i < formData.length; i++) {
      const item = formData[i]
      // console.log(item)
      if (item.check.required) {
        if (!item.value) {
          message.warn(item.title + '不能为空')
          check = false;
          break;
        }
      }
      if (item.field) {
        if(item.name.startsWith('date')){
          reqParams[item.field] = moment(item.value).format("YYYY-MM-DD")
        }else{
          reqParams[item.field] = item.value;
        }
       
      }
    }
    if (!check) return;

    // return console.log(reqParams);
    props.onPreviewFormSubmit(reqParams);
  }

  return (
    <Form
      name="basic"
      autoComplete="off"
    >
      <div className="preview-layoutBox"  >
        {
          formData.map((item: any, index: number) => {

            return (item.fieldPermissions.show && fieldShowRule(item.id)) ?
              (
                <div
                  className={
                    `compItem width-${item.span}  ${item.inline ? 'compItem-inline' : ''}`
                  }
                  key={item.id}
                >
                  {item.showTitle ? (
                    <h4 className="tit"> {item.check.required && <span className="req">*</span>} {item.title}</h4>
                  ) : null}

                  {
                    !item.inline && (
                      item.describe && <p className="desc">{item.describe}</p>
                    )
                  }
                  <div className="item">
                    {
                      item.name === 'radio' ? radioRender(item, index)
                        : item.name === 'input' ? InputRender(item, index)
                          : item.name === 'select' ? selectRender(item, index)
                            : item.name === 'datePicker' ? datePickerRender(item, index)
                              : item.name === 'dateRange' ? dateRangeRender(item, index)
                                : item.name === 'checkbox' ? checkboxRender(item, index)
                                  : item.name === 'upload' ? uploadRender(item, index)
                                    : item.name === 'staffTree' ? staffTreeRender(item, index)
                                      : item.name === 'orgTree' ? orgTreeRender(item, index)
                                        : item.name === 'splitLine' ? splitLineRender(item, index)
                                          : item.name === 'subForm' ? subFormRender(item, index)
                                            : null
                    }
                  </div>

                  {
                    item.inline && (
                      item.describe && <p className="desc">{item.describe}</p>
                    )
                  }

                </div>
              ) : null
          })
        }


      </div>

      <div className="btns">
        <Button type="primary" onClick={submit}>提交</Button>
      </div>
    </Form>
  )
}
export default PreviewForm;
